package org.jcat.toolkit.jdkapi.script;


import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * Created by hejinxu on 2017/3/10.
 */
public class JavascriptCallTest {


    public static void main(String[] args) throws ScriptException, IOException, NoSuchMethodException, URISyntaxException {

        test("world");

        test2();

        testScriptVariables();

        testScriptInterface();

        testCallFunFromFile();

        testCallFunFromFile2();

    }


    /*
     * 加载脚本引擎，并在java中调用js方法
     */
    public static void test2() {
        ScriptEngineManager manager = new ScriptEngineManager();

        ScriptEngine engine = manager.getEngineByName("javascript");
        try {
            String str = "1&1";
            Integer d = (Integer) engine.eval(str);
            Integer i = d.intValue();
            System.out.println(i);
        } catch (ScriptException ex) {
            ex.printStackTrace();
        }

    }


    /*
     * 在java中调用js，jdk1.6中有加载js引擎类，然后由它来调用js方法。
     * 并通过JDK平台给script的方法中的形参赋值
     */
    public static void test(String name) {
        ScriptEngineManager sem = new ScriptEngineManager();
    /*
     *sem.getEngineByExtension(String extension)参数为js
      sem.getEngineByMimeType(String mimeType) 参数为application/javascript 或者text/javascript
      sem.getEngineByName(String shortName)参数为js或javascript或JavaScript
     */
        ScriptEngine se = sem.getEngineByName("js");
        try {
            String script = "function say(){ return 'hello,'+'" + name + "'; }";
            se.eval(script);
            Invocable inv2 = (Invocable) se;
            String res = (String) inv2.invokeFunction("say", name);
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /*
     * 演示如何将java中对象作为js中全局变量，同时演示将file类赋给脚本语言，并获得其属性。
     */
    public static void testScriptVariables() {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("js");
        File file = new File("c:\\windows");
        engine.put("f", file);
        try {
            engine.eval("print('path:'+f.getPath())");//无法使用alert方法
        } catch (ScriptException e) {
            e.printStackTrace();
        }

    }


    /*
 * 演示如何在java中如何通过线程来启动一个js方法
 */
    public static void testScriptInterface() throws ScriptException {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("js");
        String script = "var obj=new Object();obj.run=function(){print('test thread')}";
        engine.eval(script);
        Object obj = engine.get("obj");//获取js中对象
        Invocable inv = (Invocable) engine;
        Runnable r = inv.getInterface(obj, Runnable.class);
        Thread t = new Thread(r);
        t.start();

    }

    public static void testCallFunFromFile() throws IOException, ScriptException, NoSuchMethodException, URISyntaxException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");

        URL path = JavascriptCallTest.class.getResource("/");
        System.out.println(path.getFile());


        String jsFileName = "expression.js";   // 读取js文件

        FileReader reader = new FileReader(path.getFile() + jsFileName);   // 执行指定脚本
        engine.eval(reader);

        if (engine instanceof Invocable) {
            Invocable invoke = (Invocable) engine;    // 调用merge方法，并传入两个参数
            // c = merge(2, 3);

            Double c = (Double) invoke.invokeFunction("merge", 2, 3);

            System.out.println("c = " + c);
        }
        reader.close();
    }

    public static void testCallFunFromFile2() throws IOException, ScriptException, NoSuchMethodException, URISyntaxException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");

        URL path = JavascriptCallTest.class.getResource("/");
        //System.out.println(path.getFile());


        String jsFileName = "encdec.js";   // 读取js文件

        FileReader reader = new FileReader(path.getFile() + jsFileName);   // 执行指定脚本
        engine.eval(reader);

        if (engine instanceof Invocable) {
            Invocable invoke = (Invocable) engine;    // 调用merge方法，并传入两个参数

            long l1 = System.currentTimeMillis();
            for(int i = 0; i < 1000; i++) {
                String c = (String) invoke.invokeFunction("des", "test");
                System.out.println("c: " + c);
            }
            long l2 = System.currentTimeMillis();
            System.out.println(l2 - l1);
        }
        reader.close();
    }

}
